package com.zhang.gulimall.product.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.mysql.cj.util.StringUtils;
import com.zhang.gulimall.common.constant.ProductConstant;
import com.zhang.gulimall.common.to.SkuHasStockTo;
import com.zhang.gulimall.common.to.SkuReductionTo;
import com.zhang.gulimall.common.to.SpuBoundTo;
import com.zhang.gulimall.common.to.es.SkuEsModel;
import com.zhang.gulimall.common.utils.R;
import com.zhang.gulimall.product.dao.*;
import com.zhang.gulimall.product.entity.*;
import com.zhang.gulimall.product.feign.CouponFeignService;
import com.zhang.gulimall.product.feign.EsFeignService;
import com.zhang.gulimall.product.feign.WareFeignService;
import com.zhang.gulimall.product.service.*;
import com.zhang.gulimall.product.vo.*;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zhang.gulimall.common.utils.PageUtils;
import com.zhang.gulimall.common.utils.Query;

import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;


@Service("spuInfoService")
public class SpuInfoServiceImpl extends ServiceImpl<SpuInfoDao, SpuInfoEntity> implements SpuInfoService {

    @Resource
    AttrDao attrDao;

    @Resource
    SkuInfoService skuInfoService;

    @Resource
    SpuInfoDescDao spuInfoDescDao;

    @Resource
    SpuImagesService spuImagesService;

    @Resource
    SkuImagesService skuImagesService;

    @Resource
    ProductAttrValueService productAttrValueService;

    @Resource
    SkuSaleAttrValueService skuSaleAttrValueService;

    @Resource
    CouponFeignService couponFeignService;

    @Resource
    BrandDao brandDao;

    @Resource
    CategoryDao categoryDao;

    @Resource
    WareFeignService wareFeignService;

    @Resource
    EsFeignService esFeignService;


    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        IPage<SpuInfoEntity> page = this.page(
                new Query<SpuInfoEntity>().getPage(params),
                new QueryWrapper<>()
        );

        return new PageUtils(page);
    }

    @Transactional
    @Override
    public void saveSpuInfo(SpuSaveVo spuInfo) {
        //1 spu基本信息
        SpuInfoEntity spuInfoEntity = new SpuInfoEntity();
        BeanUtils.copyProperties(spuInfo,spuInfoEntity);
        this.baseMapper.insert(spuInfoEntity);
        //2 spu描述图片
        SpuInfoDescEntity spuInfoDescEntity = new SpuInfoDescEntity();
        spuInfoDescEntity.setSpuId(spuInfoEntity.getId());
        spuInfoDescEntity.setDecript(String.join(",",spuInfo.getDecript()));
        spuInfoDescDao.insert(spuInfoDescEntity);
        //3 spu图片
        List<String> images = spuInfo.getImages();
        List<SpuImagesEntity> c1 = images.stream().map(img -> {
            SpuImagesEntity imagesEntity = new SpuImagesEntity();
            imagesEntity.setImgUrl(img);
            imagesEntity.setSpuId(spuInfoEntity.getId());
            return imagesEntity;
        }).distinct().collect(Collectors.toList());
        spuImagesService.saveBatch(c1);
        //4 bounds
        Bounds bounds = spuInfo.getBounds();
        SpuBoundTo spuBoundTo = new SpuBoundTo();
        BeanUtils.copyProperties(bounds,spuBoundTo);
        spuBoundTo.setSpuId(spuInfoEntity.getId());
        R r = couponFeignService.saveBounds(spuBoundTo);
        //5 baseAttr
        List<BaseAttrs> baseAttrs = spuInfo.getBaseAttrs();
        List<ProductAttrValueEntity> c2 = baseAttrs.stream().map(attr -> {
            ProductAttrValueEntity p = new ProductAttrValueEntity();
            BeanUtils.copyProperties(attr, p);
            p.setSpuId(spuInfoEntity.getId());
            p.setAttrValue(attr.getAttrValues());
            p.setAttrName(attrDao.selectById(p.getAttrId()).getAttrName());
            return p;
        }).distinct().collect(Collectors.toList());
        productAttrValueService.saveBatch(c2);
        //6 sku基本信息
        List<Skus> skus = spuInfo.getSkus();
        for (Skus sku : skus) {
            SkuInfoEntity skuInfoEntity = new SkuInfoEntity();
            BeanUtils.copyProperties(sku,skuInfoEntity);
            skuInfoEntity.setBrandId(spuInfoEntity.getBrandId());
            skuInfoEntity.setCatalogId(spuInfoEntity.getCatalogId());
            skuInfoEntity.setSaleCount(0L);
            skuInfoEntity.setSpuId(spuInfoEntity.getId());
            String defaultImg = "";
            for (Images image : sku.getImages()) {
                if (image.getDefaultImg() == 1){
                    defaultImg = image.getImgUrl();
                }
            }
            skuInfoEntity.setSkuDefaultImg(defaultImg);
            skuInfoService.save(skuInfoEntity);
            String skuId = skuInfoEntity.getSkuId();
            //保存sku图片
            List<SkuImagesEntity> c3 = sku.getImages().stream().map(img -> {
                SkuImagesEntity skuImagesEntity = new SkuImagesEntity();
                skuImagesEntity.setSkuId(skuId);
                skuImagesEntity.setImgUrl(img.getImgUrl());
                skuImagesEntity.setDefaultImg(img.getDefaultImg());
                return skuImagesEntity;
            }).filter(entity-> StringUtils.isEmptyOrWhitespaceOnly(entity.getImgUrl())).collect(Collectors.toList());
            skuImagesService.saveBatch(c3);
            //保存销售属性
            List<Attr> attrs = sku.getAttr();
            List<SkuSaleAttrValueEntity> c4 = attrs.stream().map(attr -> {
                SkuSaleAttrValueEntity skuSaleAttrValueEntity = new SkuSaleAttrValueEntity();
                BeanUtils.copyProperties(attr, skuSaleAttrValueEntity);
                skuSaleAttrValueEntity.setSkuId(skuId);
                return skuSaleAttrValueEntity;
            }).collect(Collectors.toList());
            skuSaleAttrValueService.saveBatch(c4);
            //优惠满减
            SkuReductionTo skuReductionTo = new SkuReductionTo();
            BeanUtils.copyProperties(sku,skuReductionTo);
            skuReductionTo.setSkuId(skuId);
            couponFeignService.saveSkuReduction(skuReductionTo);
        }
    }

    @Override
    public PageUtils queryPageByParams(Map<String, Object> params) {
        QueryWrapper<SpuInfoEntity> wrapper = new QueryWrapper<>();
        String catelogId = (String) params.get("catelogId");
        String brandId = (String) params.get("brandId");
        String key = (String) params.get("key");
        String status = (String) params.get("status");
        if (!StringUtils.isEmptyOrWhitespaceOnly(catelogId) && !catelogId.equals("0")){
            wrapper.lambda().eq(SpuInfoEntity::getCatalogId,catelogId);
        }
        if (!StringUtils.isEmptyOrWhitespaceOnly(brandId) && !brandId.equals("0")){
            wrapper.lambda().eq(SpuInfoEntity::getBrandId,brandId);
        }
        if (!StringUtils.isEmptyOrWhitespaceOnly(status)){
            wrapper.lambda().eq(SpuInfoEntity::getPublishStatus,status);
        }
        if (!StringUtils.isEmptyOrWhitespaceOnly(key)){
            wrapper.and((w)->{
                w.lambda().like(SpuInfoEntity::getSpuName,key);
                w.lambda().or().like(SpuInfoEntity::getSpuDescription,key);
            });
        }
        IPage<SpuInfoEntity> page = this.page(
                new Query<SpuInfoEntity>().getPage(params),
                wrapper
        );

        return new PageUtils(page);
    }

    @Override
    public void up(String spuId) {

        //筛选出对应spu的attr属性
        List<ProductAttrValueEntity> list = productAttrValueService.list(new QueryWrapper<ProductAttrValueEntity>().lambda().eq(ProductAttrValueEntity::getSpuId, spuId));
        QueryWrapper<AttrEntity> wrapper1 = new QueryWrapper<>();
        wrapper1.lambda().eq(AttrEntity::getSearchType,1);
        List<String> collect = attrDao.selectList(wrapper1).stream().map(AttrEntity::getAttrId).collect(Collectors.toList());
        for (String s : collect) {
            list = list.stream().filter(l1-> !l1.getAttrId().equals(s)).collect(Collectors.toList());
        }
        List<ProductAttrValueEntity> finalList = list;

        QueryWrapper<SkuInfoEntity> wrapper = new QueryWrapper<>();
        wrapper.lambda().eq(SkuInfoEntity::getSpuId,spuId);
        List<SkuInfoEntity> skuInfoEntities = skuInfoService.list(wrapper);

        List<String> ids = skuInfoEntities.stream().map(SkuInfoEntity::getSkuId).collect(Collectors.toList());
        Map<String, Boolean> map = null;
        try {
            List<SkuHasStockTo> stockTos = wareFeignService.hasStock(ids);
            map = stockTos.stream().collect(Collectors.toMap(SkuHasStockTo::getSkuId, SkuHasStockTo::isHasStock));
        }catch (Exception e){
            log.error("库存服务查询异常:原因{}",e);
            return ;
        }

        Map<String, Boolean> finalMap = map;
        List<SkuEsModel> models = skuInfoEntities.stream().map(sku -> {
            SkuEsModel skuEsModel = new SkuEsModel();
            BeanUtils.copyProperties(sku, skuEsModel);
            skuEsModel.setSkuPrice(sku.getPrice());
            skuEsModel.setSkuImg(sku.getSkuDefaultImg());

            //查询是否有库存
            if (finalMap.size()>0) {
                skuEsModel.setHasStock(finalMap.get(sku.getSkuId()));
            } else {
                skuEsModel.setHasStock(true);
            }
            //todo 热度评分
            skuEsModel.setHotScore(0L);
            //查询品牌和分类
            BrandEntity brandEntity = brandDao.selectById(sku.getBrandId());
            skuEsModel.setBrandName(brandEntity.getName());
            skuEsModel.setBrandImg(brandEntity.getLogo());
            CategoryEntity categoryEntity = categoryDao.selectById(sku.getCatalogId());
            skuEsModel.setCatalogName(categoryEntity.getName());
            //attr赋值
            for (ProductAttrValueEntity entity : finalList) {
                SkuEsModel.Attrs attrs = new SkuEsModel.Attrs();
                BeanUtils.copyProperties(entity, attrs);
                if (skuEsModel.getAttrs()==null){
                    skuEsModel.setAttrs(new ArrayList<>());
                }
                skuEsModel.getAttrs().add(attrs);
            }
            return skuEsModel;
        }).collect(Collectors.toList());

        // 保存到es中
        R up = esFeignService.up(models);
        // 修改商品状态
        if(up.getCode()==0){
            // es保存成功
            SpuInfoEntity spuInfoEntity = baseMapper.selectById(spuId);
            spuInfoEntity.setPublishStatus(ProductConstant.ProductEnum.UP.getCode());
            baseMapper.updateById(spuInfoEntity);
        } else {

        }
    }

    @Override
    public SpuInfoEntity getSpuBySkuId(String skuId) {
        SkuInfoEntity sku = skuInfoService.getById(skuId);
        return this.getById(sku.getSpuId());
    }
}